/**
 * axios请求封装
 * @author 木人心
 * @version 1.1.2
 */
import axios, { AxiosError } from 'axios'
import settings from '@/settings'
import { axiosAuthConfig, axiosConfig, cancelTokenConfig, statusCodeConfig } from '@utils/request/config'
import { ResultPayload } from '@utils/request/type'
import router from '@/router'
import { LogLevelEnum, RequestLog } from '@utils/log'
import { cancelTokenHandle } from '@utils/request/cancelToken'
import { FrequencyMessage } from '@utils/request/message'
import { getToken, removeToken } from '@utils/authorization/token'
import Authorization from '@utils/authorization'

// region TODO 创建请求实例
const baseURL = settings.UseProxy ? (process.env.NODE_ENV === 'production' ? settings.URL.BASE_URL : '/dev') : settings.URL.BASE_URL
const request = axios.create({ baseURL, ...axiosConfig })
// endregion

// region TODO 初始化Token
const token = getToken()
token && (request.defaults.headers.common[axiosAuthConfig.authorizationKey] = token)
// endregion

// region TODO 异常状态处理
const errorStatusHandle = {
  // 403(){}
}
// 为未授权状态添加异常处理
errorStatusHandle[axiosAuthConfig.unauthorizedCode] = () => {
  // 如果有令牌，删除令牌并提示令牌失效
  if (getToken()) {
    removeToken()
    FrequencyMessage.warning('登录信息已过期')
  }
  router.replace({ name: 'Login' })
}
// 为异地登录状态添加异常处理
errorStatusHandle[axiosAuthConfig.remoteLoginCode] = () => {
  removeToken()
  FrequencyMessage.warning('您的账号已在其他设备登录')
  router.replace({ name: 'Login' })
}
// endregion

// region TODO 请求拦截器
// 记录请求信息

if (cancelTokenConfig.isUse) {
  request.interceptors.request.use(
    async config => {
      // config.headers[axiosAuthConfig.authorizationKey] ??= (request.defaults.headers.common[axiosAuthConfig.authorizationKey] || Authorization.token)
      config.headers[axiosAuthConfig.authorizationKey] = Authorization.token
      let logId
      if (config.toLog !== false) logId = await RequestLog.request(config)
      cancelTokenHandle(config, logId)
      return config
    }
  )
} else {
  request.interceptors.request.use(
    config => {
      if (config.toLog !== false) RequestLog.request(config)
      return config
    })
}

// endregion

// region TODO 响应拦截器
request.interceptors.response.use(
  response => {
    RequestLog.response(response)
    const rdata = response.data
    // 处理状态异常
    errorStatusHandle[rdata.code] && errorStatusHandle[rdata.code]()
    response.result = function (showMsg = true) {
      return new Promise<ResultPayload>((resolve, reject) => {
        // 获取”状态执行“配置
        const codeConfig = statusCodeConfig.code[rdata.code] || statusCodeConfig.code.default
        // 是否继续运行
        codeConfig.break ? reject(rdata) : resolve(rdata)
        // 是否提示信息
        showMsg && codeConfig.message && FrequencyMessage.warning(rdata.msg || '未知异常')
      })
    }
    return response
  },
  (error: AxiosError) => {
    if (error.response) { // 响应出的错
      RequestLog.response(error.response, LogLevelEnum.ERROR)
      // 获取错误状态
      const code = error.response.status
      // 如果有状态异常处理按异常处理走，如果没有将错误提示出来
      if (errorStatusHandle[code]) {
        errorStatusHandle[code] && errorStatusHandle[code]()
      } else {
        const message = statusCodeConfig.status[Number(code)] || statusCodeConfig.status.default
        FrequencyMessage.error(`【${code}】${message}`)
      }
    } else { // 请求出的错
      if (!['CanceledError'].includes(error.message)) {
        if (error.message.indexOf('timeout') > -1) {
          FrequencyMessage.warning('请求超时，请稍后重试')
        } else if (error.message === 'Network Error') {
          FrequencyMessage.error('网络错误，请检查网络')
        }
      }
    }
    return Promise.reject(error)
  }
)
// endregion

export default request
